package mianshi;

/**
 * GCRoots 测试：虚拟机栈（栈帧中的局部变量）中引用的对象作为GCRoots
 * -Xms1024m -Xmx1024m -Xmn512m -XX:+PrintGCDetails
 * <p>
 * 扩展：虚拟机栈中存放了编译器可知的八种基本数据类型,对象引用,returnAddress类型（指向了一条字节码指令的地址）
 *
 * @author ljl
 */
class TestGCRoots01 {
    private int _10MB = 10 * 1024 * 1024;
    private byte[] memory = new byte[8 * _10MB];

    public static void main(String[] args) {
        method01();
        System.out.println("返回main方法");
        TestGCRoots01 t = new TestGCRoots01();
        System.gc();
        System.out.println("第二次GC完成");
    }

    public static void method01() {
        TestGCRoots01 t = new TestGCRoots01();
        System.gc();
        System.out.println("第一次GC完成");
    }
}

/**
 * 测试方法区中的静态变量引用的对象作为GCRoots
 * -Xms1024m -Xmx1024m -Xmn512m -XX:+PrintGCDetails
 * <p>
 * 扩展：方法区存与堆一样,是各个线程共享的内存区域,用于存放已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。
 *
 * @author ljl
 */
class TestGCRoots02 {
    private static int _10MB = 10 * 1024 * 1024;
    private byte[] memory;

    private static TestGCRoots02 t;

    public TestGCRoots02(int size) {
        memory = new byte[size];
    }

    public static void main(String[] args) {
        TestGCRoots02 t2 = new TestGCRoots02(4 * _10MB);
        t2.t = new TestGCRoots02(8 * _10MB);
        t2 = null;
        System.gc();
    }
}

/**
 * 测试常量引用对象作为GCRoots
 * 注意：t修饰符如果只是final会被回收，static final不会被回收，所以static final 才是常量的正确写法
 * -Xms1024m -Xmx1024m -Xmn512m -XX:+PrintGCDetails
 *
 * @author ljl
 */
class TestGCRoots03 {
    private static int _10MB = 10 * 1024 * 1024;
    private static final TestGCRoots03 t = new TestGCRoots03(8 * _10MB);
    private byte[] memory;

    public TestGCRoots03(int size) {
        memory = new byte[size];
    }

    public static void main(String[] args) {
        TestGCRoots03 t3 = new TestGCRoots03(4 * _10MB);
        t3 = null;
        System.gc();
    }
}

/**
 * 测试成员变量引用对象是否可作为GCRoots
 * -Xms1024m -Xmx1024m -Xmn512m -XX:+PrintGCDetails
 *
 * @author ljl
 */
class TestGCRoots04 {
    private static int _10MB = 10 * 1024 * 1024;
    private TestGCRoots04 t;
    private byte[] memory;

    public TestGCRoots04(int size) {
        memory = new byte[size];
    }

    public static void main(String[] args) {
        TestGCRoots04 t4 = new TestGCRoots04(4 * _10MB);
        t4.t = new TestGCRoots04(8 * _10MB);
        t4 = null;
        System.gc();
    }
}